"""
@Time   ：2022/3/21  2:58
@Author ：Li
@decs   ：shot
"""
import os
import sys
import threading
import time
import configparser
import math
from PIL import Image
from io import BytesIO


PROJECT_PATH = os.path.dirname(__file__)


class LogW:
    def __new__(cls, *args, **kwargs):
        if not hasattr(cls, '_instance'):
            with threading.Lock():
                LogW._instance = super().__new__(cls)
        return LogW._instance

    def __init__(self):
        self.log_path = os.path.join(PROJECT_PATH, "output_log.txt")

    def log_clean(self):
        with open(self.log_path, 'w') as f:
            f.close()

    def log_write(self, msg):
        with open(self.log_path, 'a') as f:
            t = time.strftime("%Y%m%d_%H%M%S", time.localtime(time.time()))
            print("{}  {}".format(t, msg))
            f.writelines("{}  {}\n".format(t, msg))
            f.close()


class Config:
    path_config = None
    delete_mobile_cache = None
    delete_computer_cache = None
    key_shortcut = None
    key_exit = None

    def __new__(cls, *args, **kwargs):
        if not hasattr(cls, '_instance'):
            with threading.Lock():
                Config._instance = super().__new__(cls)
                Config._instance.get_config()
        return Config._instance

    def get_config(self):
        self.path_config = os.path.join(PROJECT_PATH, "conf/config.ini")

        config = configparser.ConfigParser()
        config.read(self.path_config)
        self.delete_mobile_cache = config.getboolean('cache', 'delete_mobile_cache')
        self.delete_computer_cache = config.getboolean('cache', 'delete_computer_cache')
        self.key_shortcut = config.get('software', 'key_shortcut')
        self.key_exit = config.get('software', 'key_exit')

        LogW().log_write("delete_mobile_cache: {}".format(self.delete_mobile_cache))
        LogW().log_write("delete_computer_cache: {}".format(self.delete_computer_cache))
        LogW().log_write("key_shortcut: {}".format(self.key_shortcut))
        LogW().log_write("key_exit: {}".format(self.key_exit))
        LogW().log_write("get config success")


class ScreenShot:
    def __new__(cls, *args, **kwargs):
        if not hasattr(cls, '_instance'):
            with threading.Lock():
                ScreenShot._instance = super().__new__(cls)
        return ScreenShot._instance

    def __init__(self):
        self.image_name = "screenshot_{}.png".format(time.strftime("%Y%m%d_%H%M%S", time.localtime(time.time())))
        self.image_path_android = r"/sdcard/screencap/" + self.image_name
        self.image_path_computer = os.path.join(PROJECT_PATH, "cache", self.image_name)

        self.config = Config()

    def run(self):
        self.sceenshot_android()
        if not self.is_image_exists():
            return
        self.image_compress()
        if sys.platform == 'win32':
            self.send_msg_to_clip_win()
        elif sys.platform == 'darwin':
            self.send_msg_to_clip_mac()
        self.delete()

    def sceenshot_android(self):
        # 创建缓存文件夹
        path_cache = os.path.join(PROJECT_PATH, "cache")
        if not os.path.exists(path_cache):
            os.mkdir(path_cache)
            LogW().log_write("os.mkdir:" + path_cache)

        # 创建手机缓存文件夹
        command_mkdir = r"adb shell mkdir -p /sdcard/screencap"
        result = os.popen(command_mkdir).read()
        LogW().log_write(command_mkdir)

        # 截屏
        command_screencap = r"adb shell /system/bin/screencap -p {}".format(self.image_path_android)
        result = os.popen(command_screencap).read()
        LogW().log_write(command_screencap)

        # 发送到电脑
        command_pull = r"adb pull {} {}".format(self.image_path_android, self.image_path_computer)
        result = os.popen(command_mkdir).read()

        LogW().log_write(command_pull)
        LogW().log_write(os.popen(command_pull).read().strip('\n').strip('\r'))
        LogW().log_write("sceenshot android success")

    def is_image_exists(self):
        return True if os.path.exists(self.image_path_computer) else False

    def image_compress(self):
        """
        图片缩放
        :return:无
        """
        img = Image.open(self.image_path_computer)
        img_x, img_y = img.size
        n = math.ceil(max(img_x/1000, img_y/1000))
        LogW().log_write("image_compress:{}*{} to {}*{}".format(img_x, img_y, img_x/n, img_y/n))
        img = img.resize((int(img_x/n), int(img_y/n)))
        img.save(self.image_path_computer)
        LogW().log_write("image compress success")

    def send_msg_to_clip_win(self):
        """
        图片写入win粘贴板
        :return: 无
        """
        # 图片转换成二进制字符串
        image = Image.open(self.image_path_computer)
        output = BytesIO()
        image.save(output, 'BMP')
        data = output.getvalue()[14:]
        output.close()

        # 写入粘贴板
        import pywintypes
        import win32clipboard
        win32clipboard.OpenClipboard()
        win32clipboard.EmptyClipboard()
        win32clipboard.SetClipboardData(win32clipboard.CF_DIB, data)
        win32clipboard.CloseClipboard()

        LogW().log_write("send img to win_clip success")

    def send_msg_to_clip_mac(self):
        """
        图片写入mac粘贴板
        :return:
        """
        import subprocess
        command_clip = 'set the clipboard to (read (POSIX file "{}") as JPEG picture)'.format(self.image_path_computer)
        subprocess.run(["osascript", "-e", command_clip])

        LogW().log_write("send img to mac_clip success")

    def delete(self):
        """
        删除图片缓存
        :return:
        """
        if self.config.delete_mobile_cache:
            command_rm = r"adb shell rm {}".format(self.image_path_android)
            result = os.popen(command_rm).read()
            LogW().log_write(command_rm)
            LogW().log_write("delete mobile img_cache success")

        if self.config.delete_computer_cache and self.is_image_exists():
            os.remove(self.image_path_computer)
            LogW().log_write("os.remove:" + self.image_path_computer)
            LogW().log_write("delete computer img_cache success")


def event_screenshot():
    LogW().log_write('-'*80)
    LogW().log_write('ScreenShot start')
    ScreenShot().run()


def event_quit():
    LogW().log_write('-'*80)
    LogW().log_write('ScreenShot quit')
    sys.exit()


def main():
    LogW().log_clean()
    from pynput import keyboard
    with keyboard.GlobalHotKeys({Config().key_shortcut: event_screenshot, Config().key_exit: event_quit}) as h:
        LogW().log_write('add keyboard.GlobalHotKeys')
        h.join()


if __name__ == '__main__':
    main()
